import axios from 'axios';
import { KnowledgeFile, Conversation, Message } from '../types';

// 创建 axios 实例
const api = axios.create({
  baseURL: 'http://localhost:8086',
  headers: {
    'Content-Type': 'application/json',
  },
  withCredentials: true
});

// 添加默认的请求参数
api.defaults.params = {};

// 动态更新默认参数
const updateDefaultParams = () => {
  const token = localStorage.getItem('webToken');
  if (token) {
    api.defaults.params.token = token;
  }
};

// 初始调用一次
updateDefaultParams();

// 监听 localStorage 变化（如果需要）
window.addEventListener('storage', (event) => {
  if (event.key === 'webToken') {
    updateDefaultParams();
  }
});

// 请求拦截器 - 添加认证令牌和日志
api.interceptors.request.use(
  (config) => {
    const token = localStorage.getItem('webToken');
    if (token) {
      // 直接使用 token 值，不添加 Bearer 前缀
      config.headers.webToken = token;
      console.log('添加 webToken 头部:', token.substring(0, 15) + '...');
      
      // 如果是 GET 请求，也可以添加 token 到查询参数
      if (config.method?.toLowerCase() === 'get' && config.params) {
        config.params = {
          ...config.params,
          token
        };
        console.log('添加 token 到查询参数');
      }
    } else {
      console.warn('未找到 webToken');
    }
    
    console.log('发送请求:', config.method?.toUpperCase(), config.url, '头部:', config.headers);
    return config;
  },
  (error) => {
    console.error('请求错误:', error);
    return Promise.reject(error);
  }
);

// 响应拦截器 - 处理常见错误和日志
api.interceptors.response.use(
  response => {
    console.log('收到响应:', response.status, response.config.url);
    return response;
  },
  async error => {
    console.error('响应错误:', 
      error.response?.status || 'Network Error', 
      error.config?.url
    );
    
    const originalRequest = error.config;
    
    // 如果是 401 错误（未授权）且未尝试过重新登录
    if (error.response?.status === 401 && !originalRequest._retry) {
      originalRequest._retry = true;
      
      // 清除令牌，但不重定向
      localStorage.removeItem('webToken');
      console.error('认证失败，请重新登录');
      
      // 可以在这里触发一个全局的错误通知，而不是重定向
      // 例如：显示一个通知或者触发一个事件
      const event = new CustomEvent('authError', { 
        detail: { message: '认证已过期，请重新登录' } 
      });
      window.dispatchEvent(event);
    }
    
    // 如果是 CORS 错误或网络错误
    if (error.message === 'Network Error' || error.response?.status === 403) {
      console.error('网络错误或跨域请求被拒绝，请检查服务器 CORS 配置');
    }
    
    return Promise.reject(error);
  }
);

// 用户相关 API
export const userApi = {
  // 用户注册
  register: async (username: string, name: string, password: string, phone: string) => {
    try {
      const response = await api.post('/api/user/register', {
        username,
        name,
        password,
        phone
      });
      
      return response.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        console.error('注册请求失败:', error.response.data);
        return error.response.data;
      }
      throw error;
    }
  },

  // 用户登录
  login: async (username: string, password: string) => {
    try {
      console.log('尝试登录:', username);
      
      const response = await api.post('/api/user/login', {
        username,
        password
      });
      
      console.log('登录原始响应:', response);
      console.log('登录响应数据:', response.data);
      
      return response.data;
    } catch (error) {
      console.error('登录请求失败:', error);
      throw error;
    }
  },

  // 用户登出 - 客户端操作，无需调用后端
  logout: () => {
    localStorage.removeItem('webToken');
  }
};

// 知识库相关 API
export const knowledgeApi = {
  // 获取知识库文档列表 - 根据接口文档 /api/rag/list
  getFiles: async () => {
    try {
      const userId = localStorage.getItem('userId');
      
      if (!userId) {
        throw new Error('用户未登录或会话已过期');
      }
      
      console.log('获取知识库文档列表, 用户ID:', userId);
      
      const response = await api.get('/api/rag/list', {
        params: {
          userId
        }
      });
      
      console.log('知识库文档列表原始响应:', response);
      console.log('知识库文档列表响应数据:', response.data);
      
      // 添加数据验证和转换
      if (response.data && typeof response.data === 'object') {
        // 如果响应是标准格式 { code, msg, data }
        if (response.data.code === 1 && Array.isArray(response.data.data)) {
          return {
            code: response.data.code,
            msg: response.data.msg,
            data: response.data.data
          };
        }
        
        // 如果响应直接是数组
        if (Array.isArray(response.data)) {
          return {
            code: 1,
            msg: 'success',
            data: response.data
          };
        }
        
        // 其他情况，返回空数组
        return {
          code: response.data.code || 0,
          msg: response.data.msg || '数据格式不正确',
          data: []
        };
      }
      
      return { code: 0, msg: '响应格式不正确', data: [] };
    } catch (error) {
      console.error('获取知识库文档列表失败:', error);
      // 返回一个默认响应，避免未处理的错误
      return { code: 0, msg: '获取知识库文档列表失败', data: [] };
    }
  },
  
  // 上传文件到知识库 - 根据接口文档 /api/common/upload
  uploadFile: async (file: File) => {
    try {
      const userId = localStorage.getItem('userId');
      
      if (!userId) {
        throw new Error('用户未登录或会话已过期');
      }
      
      const formData = new FormData();
      formData.append('file', file);
      formData.append('userId', userId);
      
      console.log('上传文件, 用户ID:', userId, '文件名:', file.name);
      
      const response = await api.post('/api/common/upload', formData, {
        headers: {
          'Content-Type': 'multipart/form-data'
        }
      });
      
      console.log('文件上传响应:', response.data);
      return response.data;
    } catch (error) {
      console.error('上传文件失败:', error);
      throw error;
    }
  },
  
  // 删除知识库文件 - 根据接口文档 /api/rag/delete
  deleteFile: async (fileId: string) => {
    try {
      const userId = localStorage.getItem('userId');
      
      if (!userId) {
        throw new Error('用户未登录或会话已过期');
      }
      
      const response = await api.post('/api/rag/delete', null, {
        params: {
          fileId,
          userId
        }
      });
      
      return response.data;
    } catch (error) {
      console.error('删除文件失败:', error);
      throw error;
    }
  },
  
  // 预览知识库文件 - 根据接口文档 /api/knowledge/files/{fileId}/preview
  previewFile: async (fileId: string) => {
    try {
      const response = await api.get(`/api/knowledge/files/${fileId}/preview`);
      return response.data;
    } catch (error) {
      console.error('预览文件失败:', error);
      throw error;
    }
  },
  
  // 根据文档ID进行嵌入 - 根据接口文档 /api/rag/loadById
  embedFile: async (documentId: string) => {
    try {
      const userId = localStorage.getItem('userId');
      
      if (!userId) {
        throw new Error('用户未登录或会话已过期');
      }
      
      console.log('开始嵌入文档, 文档ID:', documentId);
      
      const response = await api.get('/api/rag/loadById', {
        params: {
          documentId
        }
      });
      
      console.log('文档嵌入响应:', response.data);
      return response.data;
    } catch (error) {
      console.error('文档嵌入失败:', error);
      // 返回一个默认响应，避免未处理的错误
      return { code: 0, msg: '文档嵌入失败', data: null };
    }
  },
  
  // 一键嵌入所有文档 - 根据接口文档 /api/rag/load
  embedAllFiles: async () => {
    try {
      const userId = localStorage.getItem('userId');
      
      if (!userId) {
        throw new Error('用户未登录或会话已过期');
      }
      
      console.log('开始一键嵌入所有文档');
      
      const response = await api.get('/api/rag/load', {
        params: {
          userId
        }
      });
      
      console.log('一键嵌入所有文档响应:', response.data);
      return response.data;
    } catch (error) {
      console.error('一键嵌入所有文档失败:', error);
      // 返回一个默认响应，避免未处理的错误
      return { code: 0, msg: '一键嵌入所有文档失败', data: null };
    }
  },
  
  // 知识库 AI 问答 - 根据接口文档 /api/rag/chat
  askQuestion: async (message: string, sessionId?: string) => {
    try {
      const userId = localStorage.getItem('userId');
      
      if (!userId) {
        throw new Error('用户未登录或会话已过期');
      }
      
      console.log('知识库问答, 用户ID:', userId, '消息:', message, '会话ID:', sessionId || '新会话');
      
      const params: any = {
        userId,
        message
      };
      
      // 如果有会话 ID，添加到参数中
      if (sessionId) {
        params.sessionId = sessionId;
      }
      
      const response = await api.get('/api/rag/chat', {
        params
      });
      
      console.log('知识库问答响应:', response.data);
      return response.data;
    } catch (error) {
      console.error('知识库问答失败:', error);
      // 返回一个默认响应，避免未处理的错误
      return { code: 0, msg: '知识库问答失败', data: null };
    }
  },
  
  // 获取知识库聊天历史 - 根据接口文档 /api/knowledge/chat/history
  getChatHistory: async (sessionId?: string) => {
    try {
      const userId = localStorage.getItem('userId');
      
      if (!userId) {
        throw new Error('用户未登录或会话已过期');
      }
      
      console.log('获取知识库会话历史, 用户ID:', userId, '会话ID:', sessionId || '所有会话');
      
      const params: any = {
        userId
      };
      
      // 如果有会话 ID，添加到参数中
      if (sessionId) {
        params.sessionId = sessionId;
      }
      
      const response = await api.get('/api/rag/detail', {
        params
      });
      
      console.log('知识库会话历史响应:', response.data);
      return response.data;
    } catch (error) {
      console.error('获取知识库会话历史失败:', error);
      // 返回一个默认响应，避免未处理的错误
      return { code: 0, msg: '获取知识库会话历史失败', data: [] };
    }
  },
  
  // 发送知识库聊天消息 - 根据接口文档 /api/knowledge/chat/send
  sendChatMessage: async (message: string, fileIds?: string[]) => {
    try {
      const response = await api.post('/api/knowledge/chat/send', {
        message,
        fileIds
      });
      return response.data;
    } catch (error) {
      console.error('发送知识库聊天消息失败:', error);
      throw error;
    }
  },
  
  // 清空知识库聊天历史 - 根据接口文档 /api/knowledge/chat/clear
  clearChatHistory: async () => {
    try {
      const response = await api.delete('/api/knowledge/chat/clear');
      return response.data;
    } catch (error) {
      console.error('清空知识库聊天历史失败:', error);
      throw error;
    }
  },
  
  // 获取知识库会话历史 - 根据接口文档 /api/rag/detail
  getChatHistory: async (sessionId?: string) => {
    try {
      const userId = localStorage.getItem('userId');
      
      if (!userId) {
        throw new Error('用户未登录或会话已过期');
      }
      
      console.log('获取知识库会话历史, 用户ID:', userId, '会话ID:', sessionId || '所有会话');
      
      const params: any = {
        userId
      };
      
      // 如果有会话 ID，添加到参数中
      if (sessionId) {
        params.sessionId = sessionId;
      }
      
      const response = await api.get('/api/rag/detail', {
        params
      });
      
      console.log('知识库会话历史响应:', response.data);
      return response.data;
    } catch (error) {
      console.error('获取知识库会话历史失败:', error);
      // 返回一个默认响应，避免未处理的错误
      return { code: 0, msg: '获取知识库会话历史失败', data: [] };
    }
  }
};

// 聊天相关 API
export const chatApi = {
  // 发送普通聊天消息 - 根据接口文档 /api/chat/common
  sendMessage: async (message: string, sessionId?: string) => {
    try {
      // 获取用户ID
      const userId = localStorage.getItem('userId') || '';
      // 获取 token
      const token = localStorage.getItem('webToken') || '';
      
      console.log('发送消息:', message);
      console.log('用户ID:', userId);
      console.log('会话ID:', sessionId);
      console.log('Token:', token.substring(0, 15) + '...');
      
      // 使用 GET 方法，参数通过 query 传递
      const response = await api.get('/api/chat/common', {
        params: {
          userId,
          message,
          sessionId,
          token // 显式添加 token 到查询参数
        },
        headers: {
          // 确保 webToken 头部正确设置
          webToken: token
        }
      });
      
      console.log('消息发送响应:', response.data);
      return response.data;
    } catch (error) {
      console.error('发送消息失败:', error);
      throw error;
    }
  },
  
  // 获取用户会话列表 - 根据接口文档 /api/session/list
  getSessionList: async () => {
    try {
      // 获取用户ID
      const userId = localStorage.getItem('userId') || '';
      
      if (!userId) {
        throw new Error('用户未登录或会话已过期');
      }
      
      console.log('获取用户会话列表, 用户ID:', userId);
      
      const response = await api.get('/api/session/list', {
        params: {
          userId
        }
      });
      
      console.log('会话列表响应:', response.data);
      return response.data;
    } catch (error) {
      console.error('获取会话列表失败:', error);
      throw error;
    }
  },
  
  // 获取会话详情 - 根据接口文档 /api/chat/detail
  getSessionDetail: async (sessionId: string) => {
    try {
      // 获取用户ID
      const userId = localStorage.getItem('userId') || '';
      
      if (!userId || !sessionId) {
        throw new Error('用户未登录或会话ID无效');
      }
      
      console.log('获取会话详情, 会话ID:', sessionId, '用户ID:', userId);
      
      const response = await api.get('/api/chat/detail', {
        params: {
          userId,
          sessionId
        }
      });
      
      console.log('会话详情响应:', response.data);
      
      // 添加数据验证
      if (response.data && response.data.code === 1) {
        if (!Array.isArray(response.data.data)) {
          console.warn('会话详情数据不是数组:', response.data.data);
          response.data.data = []; // 确保是数组
        }
      }
      
      return response.data;
    } catch (error) {
      console.error('获取会话详情失败:', error);
      throw error;
    }
  },
  
  // 获取会话列表 - 根据接口文档 /api/conversations
  getConversations: async () => {
    try {
      const response = await api.get('/api/conversations');
      return response.data;
    } catch (error) {
      console.error('获取会话列表失败:', error);
      throw error;
    }
  },
  
  // 获取会话详情 - 根据接口文档 /api/conversations/{conversationId}
  getConversation: async (conversationId: string) => {
    try {
      const response = await api.get(`/api/conversations/${conversationId}`);
      return response.data;
    } catch (error) {
      console.error('获取会话详情失败:', error);
      throw error;
    }
  },
  
  // 创建新会话
  createSession: async () => {
    try {
      const response = await api.post('/api/session/create');
      return response.data;
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        console.error('创建会话失败:', error.response.data);
        return error.response.data;
      }
      throw error;
    }
  },
  
  // 流式对话（使用 fetch API）
  streamChat: async (message: string, sessionId: string, callbacks: {
    onReady?: () => void;
    onTitle?: (title: string) => void;
    onContent?: (content: string) => void;
    onFinish?: () => void;
    onError?: (error: Error) => void;
  }) => {
    try {
      const token = localStorage.getItem('webToken');
      const userId = localStorage.getItem('userId');
      
      if (!token || !userId) {
        throw new Error('用户未登录或会话已过期');
      }
      
      console.log('创建流式连接, 用户ID:', userId, '会话ID:', sessionId);
      
      // 创建 fetch 请求
      const baseURL = api.defaults.baseURL || '';
      const url = `${baseURL}/api/chat/stream?message=${encodeURIComponent(message)}&sessionId=${sessionId}`;
      
      console.log('请求URL:', url);
      
      const response = await fetch(url, {
        headers: {
          'Accept': 'text/event-stream',
          'webToken': token
        },
        credentials: 'include' // 包含 cookie
      });
      
      if (!response.ok) {
        console.error('流式请求失败:', response.status, response.statusText);
        
        if (response.status === 401) {
          // 触发认证错误事件
          const event = new CustomEvent('authError', { 
            detail: { message: '认证已过期，请重新登录' } 
          });
          window.dispatchEvent(event);
        }
        
        throw new Error(`流式请求失败: ${response.status} ${response.statusText}`);
      }
      
      if (!response.body) {
        throw new Error('流式响应缺少响应体');
      }
      
      // 获取响应流并创建读取器
      const reader = response.body.getReader();
      const decoder = new TextDecoder();
      let buffer = '';
      
      // 手动触发 ready 事件
      callbacks.onReady?.();
      
      // 定义处理流的函数
      const processStream = async () => {
        try {
          // 读取数据块
          const { done, value } = await reader.read();
          
          if (done) {
            console.log('流读取完成');
            callbacks.onFinish?.();
            return;
          }
          
          // 解码数据
          const chunk = decoder.decode(value, { stream: true });
          console.log('接收到数据块:', chunk);
          buffer += chunk;
          
          // 处理接收到的数据
          // 流式响应格式为: data: {...}\n\nevent: eventName\ndata: {...}\n\n
          const events = buffer.split('\n\n');
          // 保留最后一个可能不完整的事件
          buffer = events.pop() || '';
          
          for (const eventText of events) {
            if (!eventText.trim()) continue;
            
            // 提取事件类型和数据
            const eventLines = eventText.split('\n');
            let eventType = 'message'; // 默认事件类型
            let eventData = '';
            
            for (const line of eventLines) {
              if (line.startsWith('event:')) {
                eventType = line.substring(6).trim();
              } else if (line.startsWith('data:')) {
                eventData = line.substring(5).trim();
              }
            }
            
            console.log(`处理事件 [${eventType}]:`, eventData);
            
            // 根据事件类型处理数据
            switch (eventType) {
              case 'ready':
                console.log('收到 ready 事件');
                break;
              
              case 'title':
                try {
                  const titleData = JSON.parse(eventData);
                  if (titleData && titleData.title) {
                    console.log('更新标题:', titleData.title);
                    callbacks.onTitle?.(titleData.title);
                  }
                } catch (e) {
                  console.error('解析标题数据失败:', e);
                }
                break;
              
              case 'finish':
                console.log('收到 finish 事件');
                // 结束事件会在流结束时由外部处理
                break;
              
              default:
                // 处理内容消息
                try {
                  if (eventData) {
                    // 尝试解析 JSON
                    try {
                      const jsonData = JSON.parse(eventData);
                      
                      // 尝试处理不同的 JSON 结构
                      if (jsonData.path === 'content' && jsonData.operation === 'APPEND' && jsonData.value) {
                        // 操作类型的消息
                        console.log('追加内容:', jsonData.value);
                        callbacks.onContent?.(jsonData.value);
                      } else if (jsonData.content !== undefined) {
                        // 具有 content 字段的消息
                        console.log('接收内容:', jsonData.content);
                        callbacks.onContent?.(jsonData.content);
                      } else {
                        // 无法识别的 JSON 结构，尝试寻找任何可能的文本内容
                        const possibleContent = jsonData.text || jsonData.message || jsonData.value || eventData;
                        console.log('使用推断内容:', possibleContent);
                        callbacks.onContent?.(possibleContent);
                      }
                    } catch (e) {
                      // 不是 JSON，作为纯文本处理
                      console.log('作为纯文本处理:', eventData);
                      callbacks.onContent?.(eventData);
                    }
                  }
                } catch (e) {
                  console.error('处理消息内容失败:', e);
                }
                break;
            }
          }
          
          // 继续处理流
          processStream();
        } catch (error) {
          console.error('处理流数据时出错:', error);
          callbacks.onError?.(error instanceof Error ? error : new Error('处理流数据失败'));
        }
      };
      
      // 开始处理流
      processStream();
      
      // 返回关闭连接的函数
      return () => {
        console.log('关闭流式连接');
        reader.cancel();
      };
    } catch (error) {
      console.error('流式对话失败:', error);
      callbacks.onError?.(error instanceof Error ? error : new Error('流式对话失败'));
      return () => {}; // 返回空函数
    }
  },
  
  // 删除会话 - 根据接口文档 /api/session/delete
  deleteConversation: async (sessionId: string) => {
    try {
      const userId = localStorage.getItem('userId') || '';
      
      if (!userId) {
        throw new Error('用户未登录或会话已过期');
      }
      
      console.log('删除会话, 会话ID:', sessionId, '用户ID:', userId);
      
      const response = await api.post('/api/session/delete', null, {
        params: {
          sessionId,
          userId
        }
      });
      
      console.log('删除会话响应:', response.data);
      return response.data;
    } catch (error) {
      console.error('删除会话失败:', error);
      throw error;
    }
  }
};

// 网络搜索 API
export const searchApi = {
  // 执行网络搜索 - 根据接口文档 /api/search
  search: async (query: string) => {
    try {
      const response = await api.post('/api/search', {
        query
      });
      return response.data;
    } catch (error) {
      console.error('网络搜索失败:', error);
      throw error;
    }
  },
  
  // 联网搜索对话 - 根据接口文档 /api/webSearch/chat
  webSearchChat: async (message: string, sessionId?: string) => {
    try {
      const userId = localStorage.getItem('userId');
      
      if (!userId) {
        throw new Error('用户未登录或会话已过期');
      }
      
      console.log('联网对话, 用户ID:', userId, '消息:', message, '会话ID:', sessionId || '新会话');
      
      const params: any = {
        userId,
        message
      };
      
      // 如果有会话 ID，添加到参数中
      if (sessionId) {
        params.sessionId = sessionId;
      }
      
      const response = await api.get('/api/webSearch/chat', {
        params
      });
      
      console.log('联网对话响应:', response.data);
      return response.data;
    } catch (error) {
      console.error('联网对话失败:', error);
      // 返回一个默认响应，避免未处理的错误
      return { code: 0, msg: '联网对话失败', data: null };
    }
  }
};

// 用户设置 API
export const settingsApi = {
  // 获取用户设置 - 根据接口文档 /api/settings
  getSettings: async () => {
    try {
      const response = await api.get('/api/settings');
      return response.data;
    } catch (error) {
      console.error('获取用户设置失败:', error);
      throw error;
    }
  },
  
  // 更新用户设置 - 根据接口文档 /api/settings
  updateSettings: async (settings: {
    sidebarCollapsed?: boolean;
    theme?: 'light' | 'dark';
    language?: string;
  }) => {
    try {
      const response = await api.put('/api/settings', settings);
      return response.data;
    } catch (error) {
      console.error('更新用户设置失败:', error);
      throw error;
    }
  }
};

export default api; 